package project22;

import java.util.*;

/**
 * 习题类 (Exercise class)
 * Represents a collection of arithmetic problems
 */
class Exercise {
    private List<ArithmeticProblem> problems;
    private int totalProblems;

    // Constructor
    public Exercise(int totalProblems) {
        this.totalProblems = totalProblems;
        this.problems = new ArrayList<>();
    }

    /**
     * ② 产生一定数量习题的方法 (Generate a specific number of problems)
     */
    public void generateProblems() {
        Random random = new Random();
        Set<String> generatedKeys = new HashSet<>();
        problems.clear();

        // Ensure we have both addition and subtraction problems
        int additionCount = 0;
        int subtractionCount = 0;

        // Generate at least 5 addition problems
        while (additionCount < 5 && problems.size() < totalProblems) {
            int num1 = random.nextInt(101);
            int num2 = random.nextInt(101 - num1); // Ensure sum <= 100
            String key = num1 + "+" + num2;

            if (!generatedKeys.contains(key)) {
                problems.add(new ArithmeticProblem(num1, num2, '+'));
                generatedKeys.add(key);
                additionCount++;
            }
        }

        // Generate at least 5 subtraction problems
        while (subtractionCount < 5 && problems.size() < totalProblems) {
            int num1 = random.nextInt(101);
            int num2 = random.nextInt(num1 + 1); // Ensure result >= 0
            String key = num1 + "-" + num2;

            if (!generatedKeys.contains(key)) {
                problems.add(new ArithmeticProblem(num1, num2, '-'));
                generatedKeys.add(key);
                subtractionCount++;
            }
        }

        // Generate remaining problems randomly
        while (problems.size() < totalProblems) {
            int operation = random.nextInt(2); // 0 for addition, 1 for subtraction

            if (operation == 0) { // Addition
                int num1 = random.nextInt(101);
                int num2 = random.nextInt(101 - num1);
                String key = num1 + "+" + num2;

                if (!generatedKeys.contains(key)) {
                    problems.add(new ArithmeticProblem(num1, num2, '+'));
                    generatedKeys.add(key);
                }
            } else { // Subtraction
                int num1 = random.nextInt(101);
                int num2 = random.nextInt(num1 + 1);
                String key = num1 + "-" + num2;

                if (!generatedKeys.contains(key)) {
                    problems.add(new ArithmeticProblem(num1, num2, '-'));
                    generatedKeys.add(key);
                }
            }
        }
    }

    /**
     * ③ 格式化显示方法 (Formatted display method)
     */
    public void displayProblems() {
        System.out.println("题目:");
        for (int i = 0; i < problems.size(); i += 5) {
            for (int j = 0; j < 5 && (i+j) < problems.size(); j++) {
                System.out.print(String.format("%-15s", problems.get(i+j).toProblemString()));
            }
            System.out.println();
        }
    }

    /**
     * ③ 格式化显示方法 with answers
     */
    public void displayProblemsWithAnswers() {
        System.out.println("题目和答案:");
        for (int i = 0; i < problems.size(); i += 5) {
            for (int j = 0; j < 5 && (i+j) < problems.size(); j++) {
                System.out.print(String.format("%-20s", problems.get(i+j).toString()));
            }
            System.out.println();
        }
    }

    /**
     * ④ 一定数量的减法方法 (Method to get a specific number of subtraction problems)
     */
    public List<ArithmeticProblem> getSubtractionProblems(int count) {
        List<ArithmeticProblem> subtractionProblems = new ArrayList<>();
        for (ArithmeticProblem problem : problems) {
            if (problem.getOperator() == '-' && subtractionProblems.size() < count) {
                subtractionProblems.add(problem);
            }
        }
        return subtractionProblems;
    }

    /**
     * ⑤ 一定数量的加法方法 (Method to get a specific number of addition problems)
     */
    public List<ArithmeticProblem> getAdditionProblems(int count) {
        List<ArithmeticProblem> additionProblems = new ArrayList<>();
        for (ArithmeticProblem problem : problems) {
            if (problem.getOperator() == '+' && additionProblems.size() < count) {
                additionProblems.add(problem);
            }
        }
        return additionProblems;
    }

    // Getters
    public List<ArithmeticProblem> getProblems() {
        return new ArrayList<>(problems);
    }

    public int getTotalProblems() {
        return totalProblems;
    }

    public int getAdditionCount() {
        int count = 0;
        for (ArithmeticProblem problem : problems) {
            if (problem.getOperator() == '+') {
                count++;
            }
        }
        return count;
    }

    public int getSubtractionCount() {
        int count = 0;
        for (ArithmeticProblem problem : problems) {
            if (problem.getOperator() == '-') {
                count++;
            }
        }
        return count;
    }
}

/**
 * 算式类 (Arithmetic problem class)
 */
class ArithmeticProblem {
    private int operand1;
    private int operand2;
    private char operator;
    private int result;

    // Constructor
    public ArithmeticProblem(int operand1, int operand2, char operator) {
        this.operand1 = operand1;
        this.operand2 = operand2;
        this.operator = operator;
        // Calculate result
        if (operator == '+') {
            this.result = operand1 + operand2;
        } else {
            this.result = operand1 - operand2;
        }
    }

    @Override
    public String toString() {
        return String.format("%2d %c %2d = %3d", operand1, operator, operand2, result);
    }

    // Problem string without answer
    public String toProblemString() {
        return String.format("%2d %c %2d =   ", operand1, operator, operand2);
    }

    // Getters
    public int getOperand1() {
        return operand1;
    }

    public int getOperand2() {
        return operand2;
    }

    public char getOperator() {
        return operator;
    }

    public int getResult() {
        return result;
    }
}

/**
 * ⑥ 习题集系统类 (Exercise system class with main entry point)
 */
public class ExerciseSystem {
    public static void main(String[] args) {
        System.out.println("欢迎使用加减法口算练习系统！");
        System.out.println("=============================================\n");

        // Create exercise with 50 problems
        Exercise exercise = new Exercise(50);

        // Generate problems
        exercise.generateProblems();

        // Display problems without answers
        exercise.displayProblems();

        System.out.println("\n---------------------------------------------");

        // Display problems with answers
        exercise.displayProblemsWithAnswers();

        System.out.println("\n统计信息:");
        System.out.println("总题数: " + exercise.getTotalProblems());
        System.out.println("加法题数量: " + exercise.getAdditionCount());
        System.out.println("减法题数量: " + exercise.getSubtractionCount());

        // Demonstrate getting specific number of addition/subtraction problems
        System.out.println("\n前5道加法题:");
        List<ArithmeticProblem> additionProblems = exercise.getAdditionProblems(5);
        for (int i = 0; i < additionProblems.size(); i++) {
            System.out.println((i+1) + ". " + additionProblems.get(i).toProblemString());
        }

        System.out.println("\n前5道减法题:");
        List<ArithmeticProblem> subtractionProblems = exercise.getSubtractionProblems(5);
        for (int i = 0; i < subtractionProblems.size(); i++) {
            System.out.println((i+1) + ". " + subtractionProblems.get(i).toProblemString());
        }

        System.out.println("\n=============================================");
        System.out.println("练习题生成完毕！");
    }
}
